package gsw.tool.pluggable.hook.handler;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;

import java.lang.reflect.Method;
import java.util.Map;

import gsw.tool.pluggable.core.Env;
import gsw.tool.pluggable.activity.ActivityProxy;
import gsw.tool.pluggable.core.PluginManager;

/**
 * ActivityManager的分发类:用来管理插件的Activity
 */
public class HandlerActivityManager extends BaseHandlerClass {

    /**
     * 初始化hookMethodHandles
     *
     * @param hookMethodHandles 所有的分发方法
     */
    @Override
    protected void init(Map<String, BaseHandlerMethod> hookMethodHandles) {
        hookMethodHandles.put("startActivity", new StartActivity());
    }

    /**
     * 从startActivity方法的参数中查找Intent参数的索引
     *
     * @param args startActivity方法的参数
     * @return Intent参数的索引：-1代表未找到
     */
    private static int findFirstIntentIndexInArgs(Object[] args) {
        if (args != null && args.length > 0) {
            int i = 0;
            for (Object arg : args) {
                if (arg != null && arg instanceof Intent) {
                    return i;
                }
                i++;
            }
        }
        return -1;
    }

    /**
     * 对ActivityManager的StartActivity进行扩展
     */
    private static class StartActivity extends BaseHandlerMethod {

        /**
         * 系统的方法执行前的操作
         *
         * @param receiver 系统对象
         * @param method   执行方法
         * @param args     执行方法的参数
         * @return 是否需要执行系统的方法
         */
        @Override
        protected boolean beforeInvoke(Object receiver, Method method, Object[] args) {
            Intent intent = null;
            //从startActivity方法的参数中查找Intent参数的索引
            int index = findFirstIntentIndexInArgs(args);
            if (args != null && args.length > 1 && index >= 0) {
                intent = (Intent) args[index];
            }

            Intent newIntent = new Intent();
            //修改跳转目标为代理组件，用于跳过PMS检查
            ComponentName componentName = selectProxyActivity(intent);
            newIntent.setComponent(componentName);
            //保存真实的意图
            newIntent.putExtra(Env.EXTRA_TARGET_INTENT, intent);
            args[index] = newIntent;
            return true;
        }

        /**
         * 根据插件的意图获取代理组件的ComponentName
         * 先根据插件组件的启动模式和进程名获取可用的代理组件的ActivityInfo，然后生成代理组件的ComponentName。
         * 如果获取失败，那么直接使用默认的代理组件ActivityProxy。
         *
         * @param intent 插件的意图
         * @return 代理组件的ComponentName
         */
        private ComponentName selectProxyActivity(Intent intent) {
            if (intent != null) {
                ActivityInfo proxyInfo = PluginManager.getInstance().selectProxyActivity(intent);
                if (proxyInfo != null) {
                    return new ComponentName(proxyInfo.packageName, proxyInfo.name);
                } else {
                    return new ComponentName(PluginManager.getContext(), ActivityProxy.class);
                }
            }
            return null;
        }

        /**
         * 系统的方法执行后的操作
         *
         * @param receiver 系统对象
         * @param method   执行方法
         * @param args     执行方法的参数
         */
        @Override
        protected void afterInvoke(Object receiver, Method method, Object[] args) {
            super.afterInvoke(receiver, method, args);
        }
    }
}
